"""
脚本管理器
"""
import json
from typing import Optional, List, Dict, Any
from datetime import datetime
from sqlalchemy import desc, or_
from .models import Script
from .sqlalchemy_database import SQLAlchemyDatabaseManager

class ScriptManager:
    def __init__(self):
        """
        初始化脚本管理器
        """
        self.db = SQLAlchemyDatabaseManager()

    def get_script_by_id(self, script_id: int) -> Optional[Dict[str, Any]]:
        """
        根据ID获取脚本
        :param script_id: 脚本ID
        :return: 脚本信息字典或None
        """
        script = self.db.get_by_id(Script, script_id)
        return self._convert_model_to_dict(script) if script else None

    def get_script_by_name(self, name: str) -> Optional[Dict[str, Any]]:
        """
        根据名称获取脚本
        :param name: 脚本名称
        :return: 脚本信息字典或None
        """
        session, query = self.db.query_with_session(Script)
        try:
            script = query.filter(Script.name == name).first()
            return self._convert_model_to_dict(script) if script else None
        finally:
            session.close()

    def get_all_scripts(self, limit: int = None, offset: int = None) -> List[Dict[str, Any]]:
        """
        获取所有脚本
        :param limit: 限制返回数量
        :param offset: 偏移量（用于分页）
        :return: 脚本列表
        """
        session, query = self.db.query_with_session(Script)
        try:
            if limit is not None and offset is not None:
                query = query.limit(limit).offset(offset)
                
            scripts = query.all()
            return [self._convert_model_to_dict(script) for script in scripts]
        finally:
            session.close()

    def get_active_scripts(self) -> List[Dict[str, Any]]:
        """
        获取所有启用的脚本
        :return: 脚本列表
        """
        session, query = self.db.query_with_session(Script)
        try:
            scripts = query.filter(Script.status == 1).all()
            return [self._convert_model_to_dict(script) for script in scripts]
        finally:
            session.close()

    def search_scripts(self, keyword: str, limit: int = None, offset: int = None) -> List[Dict[str, Any]]:
        """
        搜索脚本
        :param keyword: 关键词
        :param limit: 限制返回数量
        :param offset: 偏移量（用于分页）
        :return: 脚本列表
        """
        session, query = self.db.query_with_session(Script)
        try:
            query = query.filter(Script.name.like(f"%{keyword}%"))
            
            if limit is not None and offset is not None:
                query = query.limit(limit).offset(offset)
                
            scripts = query.all()
            return [self._convert_model_to_dict(script) for script in scripts]
        finally:
            session.close()

    def get_script_count(self, keyword: str = None) -> int:
        """
        获取脚本总数
        :param keyword: 搜索关键词
        :return: 脚本总数
        """
        session, query = self.db.query_with_session(Script)
        try:
            if keyword:
                query = query.filter(Script.name.like(f"%{keyword}%"))
            return query.count()
        finally:
            session.close()

    def add_script(self, script_data: Dict[str, Any]) -> int:
        """
        添加新脚本
        :param script_data: 脚本数据
        :return: 新脚本的ID
        """
        try:
            print(f"原始脚本数据: {script_data}")
            script_data = self._prepare_script_data(script_data)
            print(f"处理后的脚本数据: {script_data}")
            
            script = Script(**script_data)
            print(f"创建的脚本对象: {script.__dict__}")
            
            script_id = self.db.add(script)
            print(f"保存脚本成功，返回ID: {script_id}")
            return script_id
        except Exception as e:
            import traceback
            print(f"添加脚本失败: {str(e)}\n{traceback.format_exc()}")
            raise

    def update_script(self, script_id: int, script_data: Dict[str, Any]) -> bool:
        """
        更新脚本信息
        :param script_id: 脚本ID
        :param script_data: 要更新的数据
        :return: 是否成功
        """
        script = self.db.get_by_id(Script, script_id)
        if not script:
            return False
            
        script_data = self._prepare_script_data(script_data)
        script_data['update_at'] = int(datetime.now().timestamp() * 1000)
        
        for key, value in script_data.items():
            setattr(script, key, value)
            
        self.db.update_obj(script)
        return True

    def update_script_status(self, script_id: int, status: int) -> bool:
        """
        更新脚本状态
        
        Args:
            script_id: 脚本ID
            status: 状态 0:停止 1:运行中
            
        Returns:
            bool: 更新是否成功
        """
        try:
            session = self.db.get_session()
            try:
                script = session.query(Script).filter(Script.id == script_id).first()
                if script:
                    script.status = status
                    script.update_at = int(datetime.now().timestamp() * 1000)
                    session.commit()
                    return True
                return False
            finally:
                session.close()
        except Exception as e:
            print(f"更新脚本状态失败: {str(e)}")
            return False

    def update_script_run_status(self, script_id: int, run_status: int) -> bool:
        """
        更新脚本运行状态
        
        Args:
            script_id: 脚本ID
            run_status: 运行状态 0:停止 1:运行中
            
        Returns:
            bool: 更新是否成功
        """
        try:
            session = self.db.get_session()
            try:
                script = session.query(Script).filter(Script.id == script_id).first()
                if script:
                    script.run_status = run_status
                    script.update_at = int(datetime.now().timestamp() * 1000)
                    session.commit()
                    return True
                return False
            finally:
                session.close()
        except Exception as e:
            print(f"更新脚本运行状态失败: {str(e)}")
            return False

    def update_run_status(self, script_id: int, run_status: int) -> bool:
        """
        更新脚本运行状态
        :param script_id: 脚本ID
        :param run_status: 新运行状态
        :return: 是否成功
        """
        script = self.db.get_by_id(Script, script_id)
        if not script:
            return False
            
        script.run_status = run_status
        script.update_at = int(datetime.now().timestamp() * 1000)
        
        self.db.update_obj(script)
        return True

    def update_script_times(self, script_id: int) -> bool:
        """
        更新脚本运行次数
        :param script_id: 脚本ID
        :return: 是否成功
        """
        script = self.db.get_by_id(Script, script_id)
        if not script:
            return False
            
        now = int(datetime.now().timestamp() * 1000)
        script.latest_times += 1
        script.latest_runtime = now
        script.update_at = now
        
        self.db.update_obj(script)
        return True

    def delete_script(self, script_id: int) -> bool:
        """
        删除脚本
        :param script_id: 脚本ID
        :return: 是否成功
        """
        try:
            print(f"开始删除脚本，ID: {script_id}")
            session = self.db.get_session()
            try:
                script = session.get(Script, script_id)
                if not script:
                    print(f"脚本不存在，ID: {script_id}")
                    return False
                    
                session.delete(script)
                session.commit()
                print(f"删除脚本成功，ID: {script_id}")
                return True
            except Exception as e:
                session.rollback()
                raise
            finally:
                session.close()
        except Exception as e:
            import traceback
            print(f"删除脚本失败: {str(e)}\n{traceback.format_exc()}")
            raise

    def _prepare_script_data(self, script_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        处理脚本数据，确保字段格式正确
        """
        data = script_data.copy()
        
        # 设置默认值
        now = datetime.now()
        data.setdefault('status', 1)
        data.setdefault('run_status', 0)
        data.setdefault('latest_times', 0)
        data.setdefault('create_at', now.strftime('%Y-%m-%d %H:%M:%S'))
        data.setdefault('update_at', int(now.timestamp() * 1000))  # 转换为毫秒
        data.setdefault('latest_runtime', int(now.timestamp() * 1000))  # 转换为毫秒
        
        # 确保数字字段为整数
        int_fields = ['is_auto_offer', 'order_account_id', 'node_index', 
                     'account_count', 'task_count', 'status', 'run_status', 
                     'latest_times']
        for field in int_fields:
            if field in data and data[field] is not None:
                data[field] = int(data[field])
        
        return data

    def _convert_model_to_dict(self, script: Script) -> Dict[str, Any]:
        """
        将Script模型转换为字典
        """
        if not script:
            return {}
            
        return {
            'id': script.id,
            'name': script.name,
            'is_auto_offer': script.is_auto_offer,
            'order_account_id': script.order_account_id,
            'node_index': script.node_index,
            'account_count': script.account_count,
            'task_count': script.task_count,
            'status': script.status,
            'run_status': script.run_status,
            'start_time': script.start_time,
            'end_time': script.end_time,
            'latest_runtime': script.latest_runtime,
            'latest_times': script.latest_times,
            'update_at': script.update_at,
            'create_at': script.create_at,
            'fail_desc': script.fail_desc
        }
